package org.adream.account.service;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

import javax.annotation.Resource;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.adream.account.dao.OcrIdCardDao;
import org.adream.account.dao.PersonInfoBasicDao;
import org.adream.account.dao.RealNameAuthDao;
import org.adream.account.dao.RealNameTmpDao;
import org.adream.account.dao.UserDao;
import org.adream.account.dao.UserVerifyDao;
import org.adream.account.entity.OcrIdCardEntity;
import org.adream.account.entity.RealNameAuthEntity;
import org.adream.account.entity.RealNameTmpEntity;
import org.adream.account.entity.UserEntity;
import org.adream.account.entity.UserVerifyEntity;
import org.adream.account.util.Constant;
import org.adream.account.util.DateUtils;
import org.adream.account.util.QRCodeUtil;
import org.adream.account.util.Utils;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cloopen.rest.sdk.utils.encoder.BASE64Encoder;
import com.qcloud.image.ImageClient;
import com.qcloud.image.exception.AbstractImageException;
import com.qcloud.image.request.IdcardDetectRequest;

@Component
@EnableAsync
@Lazy
public class OcrService {

	// ocr 使用次数限制 减1 (实际为5的话就是4)
	private final static Integer OCR_COUNT = 4;

	private final static Logger logger = LoggerFactory.getLogger(OcrService.class);
	
	// ocr
	@Value("${ocr.appid}")
	String OCR_APP_ID;
	
	@Value("${orc.secretid}")
	String OCR_SECRET_ID;
	
	@Value("${orc.secretkey}")
	String OCR_SECRET_KEY;
	
	@Value("${ocr.buckername}")
	String OCR_BUCKER_NAME;

	// 实名
	// 云市场分配的密钥Id
	@Value("${cert.secretid}")
	String CERT_SECRET_ID;
	// 云市场分配的密钥Key
	@Value("${cert.secretkey}")
	String CERT_SECRET_KEY;
	@Value("${cert.url}")
	String REAL_NAME_URL;

	// 认证线程池（实名和身份认证）
	@Resource
	private TaskExecutor authTaskExecutor;

	@Autowired
	OcrIdCardDao ocrIdCardDao;

	@Autowired
	RealNameAuthDao realNameAuthDao;

	@Autowired
	PersonInfoBasicDao personInfoBasicDao;

	@Autowired
	private RealNameTmpDao tmpDao;

	@Autowired
	private UserVerifyService userVerifyService;

	@Value("${image.file.path.verifypic}")
	private String verifyPicPath;

	@Autowired
	private RealNameAuthService authService;

	@Autowired
	private UserVerifyDao userVerifyDao;
	
	@Autowired 
	private UserDao userDao;
	/**
	 * 根据状态更新 实名认证表 ，同步数据 OCR已识别了信息，处理实名是否正确
	 * 
	 * @param authEntity
	 */
	@Async
	public void autoRealName(RealNameAuthEntity authEntity) {
		authTaskExecutor.execute(new Runnable() {
			public void run() {
				try {
					Map<String, Object> rMap = processRealName(authEntity);
					if (rMap != null) {
						Integer state = Integer.parseInt(String.valueOf(rMap.get("state")));
						if (state != null && (state == Constant.TWO || state == Constant.THREE)) {
							authEntity.setState(state);
							authEntity.setCheckResult(String.valueOf(rMap.get("checkResult")));
							authEntity.setAutoCheckResult(String.valueOf(rMap.get("checkResult")));
							if(state == Constant.TWO && !StringUtils.isEmpty(authEntity.getUid())) {
								//处理性别
								processSex(authEntity.getUid());
							}
						} else {
							authEntity.setState(Constant.ONE);
							authEntity.setAutoCheckResult(String.valueOf(rMap.get("checkResult")));
						}
						authService.checkAuthAndSynData(authEntity);
					} else {
						logger.error("不存在null值");
					}
				} catch (Exception e) {
					logger.warn("自动处理实名错误");
					logger.debug(e.getMessage());
				}
			}
		});

	}

	/**
	 * 返回封装
	 * 
	 * @return
	 */
	private Map<String, Object> realNameReturn(Integer state, String checkResult) {
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("state", state);
		result.put("checkResult", checkResult);
		return result;
	}

	/**
	 * 处理实名 是否正确
	 * 
	 * @param authEntity
	 * @return null时 程序出错
	 */
	private Map<String, Object> processRealName(RealNameAuthEntity authEntity) {

		String uid = authEntity.getUid();

		try {
			// 正面
			String picPath = verifyPicPath + java.io.File.separator + authEntity.getCreFrontPic();
			String imgMd5;
			try {
				imgMd5 = DigestUtils.md5Hex(new FileInputStream(new File(picPath)));
			} catch (Exception e1) {
				return realNameReturn(1, "系统找不到正面图片路径");
			}
			OcrIdCardEntity ocrIdCardEntity = ocrIdCardDao.selectByImg(imgMd5, 0);
			if (ocrIdCardEntity == null) {
				// 给后台处理 不审核
				return realNameReturn(1, "身份证正面上传次数过多");
			}
			if (ocrIdCardEntity.getOcrCode() == null || !"0".equals(ocrIdCardEntity.getOcrCode().trim())) {
				// 非身份证正确上传，审核失败
				return realNameReturn(3, "身份证上传错误");
			}
			if (!authEntity.getRealName().equals(ocrIdCardEntity.getOcrName())
					|| !authEntity.getCreNum().trim().toLowerCase().equals(ocrIdCardEntity.getOcrIdCard().trim().toLowerCase())) {
				return realNameReturn(3, "姓名或身份证号与图片识别的不一致");
			}
			//1成功 ：2：错误 3：无法验证
			int rlt = 0;
			try {
				rlt = realNameAuth(ocrIdCardEntity.getOcrName(), ocrIdCardEntity.getOcrIdCard());
			} catch (Exception e) {
				return realNameReturn(3,"实名api错误");
			}
			
			// 实名信息进我们数据库 用了 IGNORE 重复的不会重复插入
			if(rlt == 1) {
				personInfoBasicDao.insert(ocrIdCardEntity.getOcrIdCard(), ocrIdCardEntity.getOcrName());
			}else if(rlt == 2){
				return realNameReturn(3,"实名认证不通过");
			}else {
				return realNameReturn(1,"实名无法验证");
			}
			 
			// 反面
			picPath = verifyPicPath + java.io.File.separator + authEntity.getCreReversePic();
			try {
				imgMd5 = DigestUtils.md5Hex(new FileInputStream(new File(picPath)));
			} catch (Exception e1) {
				return realNameReturn(1, "系统找不到反面图片路径");

			}
			ocrIdCardEntity = ocrIdCardDao.selectByImg(imgMd5, 1);
			if (ocrIdCardEntity == null) {
				// 给后台处理 不审核
				return realNameReturn(1, "身份证反面上传次数过多");
			}
			// 判断身份证是否过期
			String[] date = null;
			if (ocrIdCardEntity.getOcrValidDate() != null) {
				try {
					date = ocrIdCardEntity.getOcrValidDate().split("-");
					if(date.length !=2) {
						return realNameReturn(1, "身份证有效期识别错误");
					}
				} catch (Exception e) {
					logger.info("uid:" + uid + "ocr背面时间截取失败，不做处理,继续可以认证");
				}
			}else {
				return realNameReturn(1, "身份证有效期未能识别");
			}
			try {
				if (date[1] != null && !"长期".equals(date[1])) {
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
					if (!DateUtils.isAfter(date[1], sdf)) {
						return realNameReturn(3, "身份证有效期过期");
					}
				}
			} catch (Exception e) {
				logger.info("uid:" + uid + "ocr身份证有效期时间转换出错，不做处理，继续可以认证");
				return realNameReturn(1, "身份证有效期处理出错");
			}

		} catch (Exception e) {
			return realNameReturn(1, "自动实名出错");
		}
		return realNameReturn(2, "实名认证成功");
//		 
//			case "-5107": //
//				flag = false;
//				msg = "反面不是身份证照片";
//				break;
//			case "-5108": // 实际错误码
//				flag = false;
//				msg = "反面身份证信息不合规范";
//				break;
//			case "-5109":
//				flag = false;
//				msg = "反面身份证照片模糊";
//				break;
//			case "-1400": // 非法的图片格式
//				// realNameAuthDao.autoProcessAuth(uid, 3, "非法的图片格式");
//				flag = false;
//				msg = "反面图片非法图片";
//				break;
//			case "-1404": // 图片无法识别
//				flag = false;
//				msg = "反面图片无法识别";
//				break;

	}

	/**
	 * 处理身份证正面 识别结果 num 0：正面 ；1：反面
	 */
	private static String ocrIdCard(ImageClient imageClient, String bucketName, String imgPath, int num) {
		String ret = null;
		logger.debug("ocr识别身份证正面");
		File[] idcardImageList = new File[1];
		idcardImageList[0] = new File(imgPath);

		IdcardDetectRequest idReq = new IdcardDetectRequest(bucketName, idcardImageList, num);

		try {
			ret = imageClient.idcardDetect(idReq);
		} catch (AbstractImageException e) {
			logger.error("ocrError!");
		}
		return ret;
	}

	private OcrIdCardEntity addOcrIdCardEntity(String imgMd5, String uid, int imgType, JSONObject jsonObject) {
		OcrIdCardEntity ocrIdCardEntity = new OcrIdCardEntity();
		ocrIdCardEntity.setImgMd5(imgMd5);
		ocrIdCardEntity.setUid(uid);
		ocrIdCardEntity.setOcrCode(jsonObject.getString("code"));
		ocrIdCardEntity.setOcrMessage(jsonObject.getString("message"));
		ocrIdCardEntity.setFilename(jsonObject.getString("filename"));
		ocrIdCardEntity.setCardType(imgType);
		// 正面信息
		if (imgType == 0 && "0".equals(ocrIdCardEntity.getOcrCode())) {
			JSONObject dataJson = JSONObject.parseObject(jsonObject.getString("data"));
			ocrIdCardEntity.setOcrName(dataJson.getString("name"));
			ocrIdCardEntity.setOcrSex(dataJson.getString("sex"));
			ocrIdCardEntity.setOcrAddress(dataJson.getString("address"));
			ocrIdCardEntity.setOcrIdCard(dataJson.getString("id"));
			ocrIdCardEntity.setOcrBirth(dataJson.getString("birth"));
			ocrIdCardEntity.setOcrNation(dataJson.getString("nation"));
		}
		// 背面信息
		if (imgType == 1 && "0".equals(ocrIdCardEntity.getOcrCode())) {
			JSONObject dataJson = JSONObject.parseObject(jsonObject.getString("data"));
			ocrIdCardEntity.setOcrAuthority(dataJson.getString("authority"));
			ocrIdCardEntity.setOcrValidDate(dataJson.getString("valid_date"));
		}

		if (ocrIdCardDao.insert(ocrIdCardEntity) == 1) {
			return ocrIdCardEntity;
		} else {
			return null;
		}

	}
	/**
	 * 
	 * @param name
	 * @param idCard
	 * @return 1：正取，2：错误，3：无法验证
	 * @throws ADreamServiceException
	 * @throws InvalidKeyException
	 * @throws NoSuchAlgorithmException
	 * @throws UnsupportedEncodingException
	 */
	private int realNameAuth(String name, String idCard)
			throws ADreamServiceException, InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
		
		// 数据库中实名信息
		String realName = personInfoBasicDao.selectNameById(idCard);
		if (realName != null) {
			if (name.equals(realName)) {
				return 1;
			} else {
				logger.debug("本地实名信息存在 ，且不一致");
				return 2;
			}
		}
		String source = "market";

		Calendar cd = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
		sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
		String datetime = sdf.format(cd.getTime());
		// 签名
		String auth = calcAuthorization(source, CERT_SECRET_ID, CERT_SECRET_KEY, datetime);
		// 请求方法
		String method = "GET";
		// 请求头
		Map<String, String> headers = new HashMap<String, String>();
		headers.put("X-Source", source);
		headers.put("X-Date", datetime);
		headers.put("Authorization", auth);

		// 查询参数
		Map<String, String> queryParams = new HashMap<String, String>();
		queryParams.put("idcard", idCard);
		queryParams.put("name", name);
		// body参数
		Map<String, String> bodyParams = new HashMap<String, String>();

		// url参数拼接
		String url = REAL_NAME_URL;
		if (!queryParams.isEmpty()) {
			url += "?" + urlencode(queryParams);
		}

		BufferedReader in = null;
		try {
			URL realUrl = new URL(url);
			HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
			conn.setConnectTimeout(5000);
			conn.setReadTimeout(5000);
			conn.setRequestMethod(method);

			// request headers
			for (Map.Entry<String, String> entry : headers.entrySet()) {
				conn.setRequestProperty(entry.getKey(), entry.getValue());
			}

			// request body
			Map<String, Boolean> methods = new HashMap<>();
			methods.put("POST", true);
			methods.put("PUT", true);
			methods.put("PATCH", true);
			Boolean hasBody = methods.get(method);
			if (hasBody != null) {
				conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

				conn.setDoOutput(true);
				DataOutputStream out = new DataOutputStream(conn.getOutputStream());
				out.writeBytes(urlencode(bodyParams));
				out.flush();
				out.close();
			}

			// 定义 BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line;
			String result = "";
			while ((line = in.readLine()) != null) {
				result += line;
			}

			 JSONObject resultObject = JSONObject.parseObject(result);
			 Integer code = resultObject.getInteger("code");
			 //0：成功 -1：系统繁忙 ；400：Bad Request ;405 Method Not Allowed;500 Api  Sercer Error
			 // 10001 appId不存在 ;10002 不合法的OKEN ；20001：非法appid ;20310 请求姓名不标准 ；20010身份证号不标准
			 //10010余额不足
			 if(code !=null && code == 10010) {
				 throw new ADreamServiceException("余额不足");
			 }
			 if(code ==null || code !=0 ) {
				 //请求状态码返回的不是0就认为无法验证
				 return 3;
			 }
			 JSONObject a = resultObject.getJSONObject("result");
			 Integer  res = a.getInteger("res");
			 switch (res) {
			case 1:	return 1; //正确
			case 2: return 2; //错误
			case 3: return 3; //无法验证
			default:
				 throw new ADreamServiceException("非法状态");
			}
		} catch (Exception e) {
			String msg = "实名错误";
			String err_msg = e.getMessage();
			if(err_msg!=null &&err_msg.length() == 4) {
				msg = err_msg;
			}
			throw new ADreamServiceException(msg);
		} finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}

	/**
	 * 实名接口 签名
	 */
	private static String calcAuthorization(String source, String secretId, String secretKey, String datetime)
			throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
		String signStr = "x-date: " + datetime + "\n" + "x-source: " + source;
		Mac mac = Mac.getInstance("HmacSHA1");
		Key sKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), mac.getAlgorithm());
		mac.init(sKey);
		byte[] hash = mac.doFinal(signStr.getBytes("UTF-8"));
		String sig = new BASE64Encoder().encode(hash);

		String auth = "hmac id=\"" + secretId + "\", algorithm=\"hmac-sha1\", headers=\"x-date x-source\", signature=\""
				+ sig + "\"";
		return auth;
	}

	private static String urlencode(Map<?, ?> map) throws UnsupportedEncodingException {
		StringBuilder sb = new StringBuilder();
		for (Map.Entry<?, ?> entry : map.entrySet()) {
			if (sb.length() > 0) {
				sb.append("&");
			}
			sb.append(String.format("%s=%s", URLEncoder.encode(entry.getKey().toString(), "UTF-8"),
					URLEncoder.encode(entry.getValue().toString(), "UTF-8")));
		}
		return sb.toString();
	}

	/**
	 * 处理身份认证 （目前支持  去远方教师身、去远方学生份认证）
	 * 去远方学生认证时根据二维码识别规则来自动处理的
	 */
	@Async
	public void autoUserVerify(UserVerifyEntity userVerifyEntity) {
		authTaskExecutor.execute(new Runnable() {
			public void run() {
				if(userVerifyEntity == null) {
					logger.info("没有教师身份信息，不处理");
					return;
				}
				if (userVerifyEntity.getRleId() == null) {
					logger.info("角色id空，不处理");
					return;
				}
				if (StringUtils.isEmpty(userVerifyEntity.getUid())
						|| StringUtils.isEmpty(userVerifyEntity.getUid().trim())) {
					logger.info("uid丢失，身份认证不处理");
					return;
				}
				RealNameAuthEntity realNameAuthEntity = realNameAuthDao.queryAuthByUidAndDr(userVerifyEntity.getUid(),
						Constant.ONE);
				// 实名已通过的 直接通过梦想教师认证
				if (realNameAuthEntity != null) {
					Integer authState = realNameAuthEntity.getState();
					if (authState != null && authState == Constant.TWO) {
						userVerifyEntity.setState(authState);
						userVerifyEntity.setCheckResult("身份认证通过");
						userVerifyEntity.setAutoCheckResult("实名认证已通过，身份实名通过");
						userVerifyService.checkVerifyAndSynData("auto", userVerifyEntity.getUid(),
								userVerifyEntity.getRleId(), userVerifyEntity);
						return;
					}
				}
				// 以下是实名未通过的 或者不存在的 需要处理实名表
				RealNameTmpEntity realNameTmp = tmpDao.queryTmpByUidAndDr(userVerifyEntity.getUid(), Constant.ONE);
				if (realNameTmp == null) {
					logger.info("身份实名中间表查询失败,不处理，uid:" + userVerifyEntity.getUid());
					userVerifyEntity.setAutoCheckResult("自动处理程序出错，身份实名表数据未找到");
					userVerifyDao.updateAutoCheckResult(userVerifyEntity);
					return;
				}
				if(realNameTmp.getCreType()==null ) {
					userVerifyEntity.setAutoCheckResult("证件类型数据丢失，不自动处理");
					userVerifyDao.updateAutoCheckResult(userVerifyEntity);
					return;
				}
				if(realNameTmp.getCreType() == 1) {
					userVerifyEntity.setAutoCheckResult("护照类型，不自动处理");
					userVerifyDao.updateAutoCheckResult(userVerifyEntity);
					return;
				}
				//其他类型
				if(realNameTmp.getCreType() == 2) {
					if(Constant.GFA_STUDENT_ID.equals(userVerifyEntity.getRleId())) {
						processVerifyByQr(userVerifyEntity,realNameTmp,realNameAuthEntity);
					} else {
						userVerifyEntity.setAutoCheckResult("其他类型，非学生身份不自动处理");
						userVerifyDao.updateAutoCheckResult(userVerifyEntity);
					}
					
					return;
				}
				
				//以下是 0 身份证类型
				if (realNameAuthEntity == null) {
					realNameAuthEntity = new RealNameAuthEntity();
				}
				// 实名信息替换最新的
				BeanUtils.copyProperties(realNameTmp, realNameAuthEntity);

				String rltMsg = authService.vaildateIdCard(realNameAuthEntity.getUid(),
						realNameAuthEntity.getCreNum());
				if (StringUtils.isEmpty(rltMsg)) {
					realNameAuthEntity.setState(Constant.ONE);
					realNameAuthEntity.setCheckResult("正在审核中,请耐心等候");
				} else {
					realNameAuthEntity.setState(Constant.THREE);
					realNameAuthEntity.setCheckResult(rltMsg);
				}

				// 实名状态 1的 开始处理实名信息
				if (realNameAuthEntity.getState() != null && realNameAuthEntity.getState() == Constant.ONE) {
					try {
						Map<String, Object> rMap = processRealName(realNameAuthEntity);
						if (rMap != null) {
							Integer state = Integer.parseInt(String.valueOf(rMap.get("state")));
							if (state != null && (state == Constant.TWO || state == Constant.THREE)) {
								realNameAuthEntity.setState(state);
								if (state == Constant.TWO) {
									realNameAuthEntity.setCheckResult("实名认证成功");
									realNameAuthEntity.setVerifySuccessts(new Date());
								} else {
									realNameAuthEntity.setCheckResult(String.valueOf(rMap.get("checkResult")));
								}
								realNameAuthEntity.setAutoCheckResult(String.valueOf(rMap.get("checkResult")));
							} else {
								realNameAuthEntity.setState(Constant.ONE);
								realNameAuthEntity.setAutoCheckResult(String.valueOf(rMap.get("checkResult")));
							}

						} else {
							logger.info("不存在的null值516");
							return;
						}
					} catch (Exception e) {
						logger.info("自动处理实名错误");
						logger.debug(e.getMessage());
						userVerifyEntity.setAutoCheckResult("自动处理程序出错，处理实名时出错521");
						userVerifyDao.updateAutoCheckResult(userVerifyEntity);
						return;
					}
				}

				realNameAuthEntity.setMts(new Date());
				int result = realNameAuthDao.replaceRealNameAuth(realNameAuthEntity);
				if (result == Constant.ZERO) {
					logger.warn("replace实名认证失败:(");
					userVerifyEntity.setAutoCheckResult("自动处理程序出错，处理实名时出错529");
					userVerifyDao.updateAutoCheckResult(userVerifyEntity);
					return;
				}

				// 1 或者 其他 审核中 身份认证也是审核中 这种情况不考虑 不用管
				// 2已通过 直接通过身份实名
				// 3没有通过 拒绝身份实名
				if (realNameAuthEntity.getState() != null && (realNameAuthEntity.getState() == Constant.TWO
						|| realNameAuthEntity.getState() == Constant.THREE)) {
					userVerifyEntity.setState(realNameAuthEntity.getState());
					userVerifyEntity.setCheckResult(realNameAuthEntity.getCheckResult());
					userVerifyEntity.setAutoCheckResult(realNameAuthEntity.getAutoCheckResult());
					userVerifyService.checkVerifyAndSynData("auto", userVerifyEntity.getUid(),
							userVerifyEntity.getRleId(), userVerifyEntity);
					return;
				} else {
					logger.info("实名状态为1 ，不处理身份认证");
					userVerifyEntity.setAutoCheckResult("身份认证失败，实名未认证成功");
					userVerifyDao.updateAutoCheckResult(userVerifyEntity);
					return;
				}
			}
		});

	}

	/**
	 * 单次处理OCR 正面或者反面
	 * 
	 * @param uid
	 * @param cardType 0：正面 ，1：反面
	 * @param picName
	 * @return
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	public OcrIdCardEntity processOCR(String uid, Integer cardType, String picName)
			throws FileNotFoundException, IOException {
		if (uid == null || picName == null) {
			logger.info("身份证" + cardType + "面uid/picName 空");
			return null;
		}
		if (cardType == null || (cardType != 0 && cardType != 1)) {
			logger.info("身份证" + cardType + "面cardType空或非法");
			return null;
		}
		String picPath = verifyPicPath + java.io.File.separator + picName;
		String picMD5 = DigestUtils.md5Hex(new FileInputStream(new File(picPath)));
		// 若存在 有概率不是我存的图（uid可能不同） 只是拿图读取的信息
		OcrIdCardEntity ocrIdCardEntity = ocrIdCardDao.selectByImg(picMD5, cardType);

		// 限制次数
		if (ocrIdCardEntity == null && ocrIdCardDao.selectCountByUidAndType(uid, cardType) > OCR_COUNT) {
			logger.info("uid:" + uid + "身份证" + cardType + "面OCR超过次数，不处理了");
			return null;
		}

		if (ocrIdCardEntity == null) {
			// ocr识别连接
			ImageClient imageClient = new ImageClient(OCR_APP_ID, OCR_SECRET_ID, OCR_SECRET_KEY,
					ImageClient.NEW_DOMAIN_recognition_image_myqcloud_com/* 根据文档说明选择域名 */);
			// 身份证
			String rlt = ocrIdCard(imageClient, OCR_BUCKER_NAME, picPath, cardType);
			ocrIdCardEntity = addOcrIdCardEntity(picMD5, uid, cardType, JSONObject.parseObject(
					JSONArray.parseArray(JSONObject.parseObject(rlt).getString("result_list")).get(0).toString()));

		}
		if (ocrIdCardEntity == null) {
			// 插入数据库失败
			logger.info("uid:" + uid + "ocr正面插入数据库信息失败，不继续执行");
			return null;
		}
		return ocrIdCardEntity;

	}
	
	/**
	 * 自动验证其他类型 是否是合法二维码  
	 * （此处目前只适用于学生身份 ）
	 * @param realNameTmp 
	 * @param userVerifyEntity 
	 * @param realNameAuthEntity 
	 */
	private void processVerifyByQr(UserVerifyEntity userVerifyEntity, RealNameTmpEntity tmpEntity, RealNameAuthEntity realNameAuthEntity) {
		if (realNameAuthEntity == null) {
			realNameAuthEntity = new RealNameAuthEntity();
		}
		// 实名信息替换最新的
		BeanUtils.copyProperties(tmpEntity, realNameAuthEntity);
		//验证 QR二维码
		String qrFile = tmpEntity.getCreFrontPic();
		if(StringUtils.isEmpty(qrFile)) {
			userVerifyEntity.setAutoCheckResult("tmp图空值，不自动处理");
			userVerifyDao.updateAutoCheckResult(userVerifyEntity);
			return;
		}
		String path = verifyPicPath + java.io.File.separator + qrFile;
		String qrString = null;
		try {
			qrString = QRCodeUtil.decode(path);
		} catch (Exception e) {
			//"qr解码出错，未自动处理"
			userVerifyEntity.setState(3);
			userVerifyEntity.setCheckResult("不是二维码或者不合规");
			userVerifyEntity.setAutoCheckResult("qr解码出错，未自动处理");
			userVerifyService.checkVerifyAndSynData("auto", userVerifyEntity.getUid(),
					userVerifyEntity.getRleId(), userVerifyEntity);
			return;
		}
		if(StringUtils.isEmpty(qrString)) {
			//"qr为空字符串"
			userVerifyEntity.setState(3);
			userVerifyEntity.setCheckResult("不是二维码或者不合规");
			userVerifyEntity.setAutoCheckResult("qr为空字符串，处理失败");
			userVerifyService.checkVerifyAndSynData("auto", userVerifyEntity.getUid(),
					userVerifyEntity.getRleId(), userVerifyEntity);
			return;
		}
		//1 二维码是否合法
		if(!qrString.contains("https://account.adream.org/account")) {
			//"qr不合法"
			userVerifyEntity.setState(3);
			userVerifyEntity.setCheckResult("不是二维码或者不合规");
			userVerifyEntity.setAutoCheckResult("qr不合法，处理失败");
			userVerifyService.checkVerifyAndSynData("auto", userVerifyEntity.getUid(),
					userVerifyEntity.getRleId(), userVerifyEntity);
			return;
		}
		//2二维码是否包含参数
		String qr = Utils.getParam(qrString,"qr");
		if(StringUtils.isEmpty(qr)) {
			//"qr参数不存在;
			userVerifyEntity.setState(3);
			userVerifyEntity.setCheckResult("不是二维码或者不合规");
			userVerifyEntity.setAutoCheckResult("qr参数不存在，处理失败");
			userVerifyService.checkVerifyAndSynData("auto", userVerifyEntity.getUid(),
					userVerifyEntity.getRleId(), userVerifyEntity);
			return;
		}
		//3参数是否找到对应用户 ，并且是去远方教师
		UserEntity userEntity = userDao.queryUserByQr(qr);
		if(userEntity == null) {
			//"qr对应用户不存在
			userVerifyEntity.setState(3);
			userVerifyEntity.setCheckResult("不是二维码或者不合规");
			userVerifyEntity.setAutoCheckResult("qr对应用户不存在，处理失败");
			userVerifyService.checkVerifyAndSynData("auto", userVerifyEntity.getUid(),
					userVerifyEntity.getRleId(), userVerifyEntity);
			return;
		}
		List<String> roleList = userDao.getUserRoleIdsByUid(userEntity.getUid());
		if(roleList == null || !roleList.contains(Constant.GFA_TEACHER_ID)) {
			//"qr对应用户未认证去远方教师
			userVerifyEntity.setState(3);
			userVerifyEntity.setCheckResult("非去远方教师认证二维码");
			userVerifyEntity.setAutoCheckResult("qr对应用户未认证去远方教师，处理失败");
			userVerifyService.checkVerifyAndSynData("auto", userVerifyEntity.getUid(),
					userVerifyEntity.getRleId(), userVerifyEntity);
			return;
		}
		//以下判断为自动实名，且身份自动通过
		userVerifyEntity.setState(2);
		userVerifyEntity.setCheckResult("认证成功");
		userVerifyEntity.setAutoCheckResult("qr识别成功，处理成功");
		userVerifyService.checkVerifyAndSynData(null, userVerifyEntity.getUid(),
				userVerifyEntity.getRleId(), userVerifyEntity);
		return;
	}
	/**
	 * 根据ocr识别结果更新性别
	 * @param uid
	 */
	private void processSex(String uid) {
		OcrIdCardEntity ocrIdCardEntity = ocrIdCardDao.searchCurrentByUid(uid);
		if(ocrIdCardEntity == null) return;
		String sex = null;
		switch (ocrIdCardEntity.getOcrSex()) {
		case "男": sex = "M"; break;
		case "女": sex = "F"; break;
		default:
			break;
		}
		if(!StringUtils.isEmpty(sex)) {
			userDao.updateSexByUid(sex,uid);
		}
	}
}
